home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
pascal
/
finput.zip
/
FINPUT.PAS
next >
Wrap
Pascal/Delphi Source File
|
1991-01-01
|
13KB
|
423 lines
unit FInput;
{$X+}
{
This unit implements a derivative of TInputLine that supports several
data types dynamically. It also provides formatted input for all the
numerical types, keystroke filtering and uppercase conversion, field
justification, and range checking.
When the field is initialized, many filtering and uppercase converions
are implemented pertinent to the particular data type.
The CheckRange and ErrorHandler methods should be overridden if the
user wants to implement then.
This is just an initial implementation and comments are welcome. You
can contact me via Compuserve. (76066,3202)
I am releasing this into the public domain and anyone can use or modify
it for their own personal use.
Copyright (c) 1990 by Allen Bauer (76066,3202)
This is version 1.1 - fixed input validation functions
}
interface
uses Objects, Drivers, Dialogs;
type
VKeys = set of char;
PFInputLine = ^TFInputLine;
TFInputLine = object(TInputLine)
ValidKeys : VKeys;
DataType,Decimals : byte;
imMode : word;
Validated, ValidSent : boolean;
constructor Init(var Bounds: TRect; AMaxLen: integer;
ChrSet: VKeys;DType, Dec: byte);
constructor Load(var S: TStream);
procedure Store(var S: TStream);
procedure HandleEvent(var Event: TEvent); virtual;
procedure GetData(var Rec); virtual;
procedure SetData(var Rec); virtual;
function DataSize: word; virtual;
procedure Draw; virtual;
function CheckRange: boolean; virtual;
procedure ErrorHandler; virtual;
end;
const
imLeftJustify = $0001;
imRightJustify = $0002;
imConvertUpper = $0004;
DString = 0;
DChar = 1;
DReal = 2;
DByte = 3;
DShortInt = 4;
DInteger = 5;
DLongInt = 6;
DWord = 7;
DDate = 8;
DTime = 9;
DRealSet : VKeys = [#1..#31,'+','-','0'..'9','.','E','e'];
DSignedSet : VKeys = [#1..#31,'+','-','0'..'9'];
DUnSignedSet : VKeys = [#1..#31,'0'..'9'];
DCharSet : VKeys = [#1..#31,' '..'~'];
DUpperSet : VKeys = [#1..#31,' '..'`','{'..'~'];
DAlphaSet : VKeys = [#1..#31,'A'..'Z','a'..'z'];
DFileNameSet : VKeys = [#1..#31,'!','#'..')','-'..'.','0'..'9','@'..'Z','^'..'{','}'..'~'];
DPathSet : VKeys = [#1..#31,'!','#'..')','-'..'.','0'..':','@'..'Z','^'..'{','}'..'~','\'];
DFileMaskSet : VKeys = [#1..#31,'!','#'..'*','-'..'.','0'..':','?'..'Z','^'..'{','}'..'~','\'];
DDateSet : VKeys = [#1..#31,'0'..'9','/'];
DTimeSet : VKeys = [#1..#31,'0'..'9',':'];
cmValidateYourself = 2000;
procedure RegisterFInputLine;
const
RFInputLine : TStreamRec = (
ObjType: 20000;
VmtLink: Ofs(typeof(TFInputLine)^);
Load: @TFInputLine.Load;
Store: @TFinputLine.Store
);
implementation
uses Views, MsgBox, StrFmt, Dos;
function CurrentDate : string;
var
Year,Month,Day,DOW : word;
DateStr : string[10];
begin
GetDate(Year,Month,Day,DOW);
DateStr := SFLongint(Month,2)+'/'
+SFLongInt(Day,2)+'/'
+SFLongInt(Year mod 100,2);
for DOW := 1 to length(DateStr) do
if DateStr[DOW] = ' ' then
DateStr[DOW] := '0';
CurrentDate := DateStr;
end;
function CurrentTime : string;
var
Hour,Minute,Second,Sec100 : word;
TimeStr : string[10];
begin
GetTime(Hour,Minute,Second,Sec100);
TimeStr := SFLongInt(Hour,2)+':'
+SFLongInt(Minute,2)+':'
+SFLongInt(Second,2);
for Sec100 := 1 to length(TimeStr) do
if TimeStr[Sec100] = ' ' then
TimeStr[Sec100] := '0';
CurrentTime := TimeStr;
end;
procedure RegisterFInputLine;
begin
RegisterType(RFInputLine);
end;
constructor TFInputLine.Init(var Bounds: TRect; AMaxLen: integer;
ChrSet: VKeys; DType, Dec: byte);
begin
if (DType in [DDate,DTime]) and (AMaxLen < 8) then
AMaxLen := 8;
TInputLine.Init(Bounds,AMaxLen);
ValidKeys:= ChrSet;
DataType := DType;
Decimals := Dec;
Validated := true;
ValidSent := false;
case DataType of
DReal,DByte,DLongInt,
DShortInt,DWord : imMode := imRightJustify;
DChar,DString,
DDate,DTime : imMode := imLeftJustify;
end;
if ValidKeys = DUpperSet then
imMode := imMode or imConvertUpper;
EventMask := EventMask or evMessage;
end;
constructor TFInputLine.Load(var S: TStream);
begin
TInputLine.Load(S);
S.Read(ValidKeys, sizeof(VKeys));
S.Read(DataType, sizeof(byte));
S.Read(Decimals, sizeof(byte));
S.Read(imMode, sizeof(word));
S.Read(Validated, sizeof(boolean));
S.Read(ValidSent, sizeof(boolean));
end;
procedure TFInputLine.Store(var S: TStream);
begin
TInputLine.Store(S);
S.Write(ValidKeys, sizeof(VKeys));
S.Write(DataType, sizeof(byte));
S.Write(Decimals, sizeof(byte));
S.Write(imMode, sizeof(word));
S.Write(Validated, sizeof(boolean));
S.Write(ValidSent, sizeof(boolean));
end;
procedure TFInputLine.HandleEvent(var Event: TEvent);
var
NewEvent: TEvent;
begin
case Event.What of
evKeyDown : begin
if (imMode and imConvertUpper) <> 0 then
Event.CharCode := upcase(Event.CharCode);
if not(Event.CharCode in [#0..#31]) then
begin
Validated := false;
ValidSent := false;
end;
if (Event.CharCode <> #0) and not(Event.CharCode in ValidKeys) then
ClearEvent(Event);
end;
evBroadcast: begin
if (Event.Command = cmReceivedFocus) and
(Event.InfoPtr <> @Self) and
((Owner^.State and sfSelected) <> 0) and
not(Validated) and not(ValidSent) then
begin
NewEvent.What := evBroadcast;
NewEvent.InfoPtr := @Self;
NewEvent.Command := cmValidateYourself;
PutEvent(NewEvent);
ValidSent := true;
end;
if (Event.Command = cmValidateYourself) and
(Event.InfoPtr = @Self) then
begin
if not CheckRange then
begin
ErrorHandler;
Select;
end
else
Validated := true;
ValidSent := false;
ClearEvent(Event);
end;
end;
end;
TInputLine.HandleEvent(Event);
end;
procedure TFInputLine.GetData(var Rec);
var
Code : integer;
begin
case DataType of
Dstring,
DDate,
DTime : TInputLine.GetData(Rec);
DChar : char(Rec) := Data^[1];
DReal : val(Data^, real(Rec) , Code);
DByte : val(Data^, byte(Rec) , Code);
DShortInt : val(Data^, shortint(Rec) , Code);
DInteger : val(Data^, integer(Rec) , Code);
DLongInt : val(Data^, longint(Rec) , Code);
DWord : val(Data^, word(Rec) , Code);
end;
end;
procedure TFInputLine.SetData(var Rec);
begin
case DataType of
DString,
DDate,
DTime : TInputLine.SetData(Rec);
DChar : Data^ := char(Rec);
DReal : Data^ := SFDReal(real(Rec),MaxLen,Decimals);
DByte : Data^ := SFLongInt(byte(Rec),MaxLen);
DShortInt : Data^ := SFLongInt(shortint(Rec),MaxLen);
DInteger : Data^ := SFLongInt(integer(Rec),MaxLen);
DLongInt : Data^ := SFLongInt(longint(Rec),MaxLen);
DWord : Data^ := SFLongInt(word(Rec),MaxLen);
end;
SelectAll(true);
end;
function TFInputLine.DataSize: word;
begin
case DataType of
DString,
DDate,
DTime : DataSize := TInputLine.DataSize;
DChar : DataSize := sizeof(char);
DByte : DataSize := sizeof(byte);
DShortInt : DataSize := sizeof(shortint);
DInteger : DataSize := sizeof(integer);
DLong